package com.practice.selenium.driver;

import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.GeckoDriverService;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.ie.InternetExplorerDriverService;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.safari.SafariDriver;
import com.practice.selenium.config.SeleniumConfig;
import com.practice.selenium.config.WebDriverConfig;

public final class WebDriverFactory {

	private static final String DRIVER_PATH_KEY_CHROME = ChromeDriverService.CHROME_DRIVER_EXE_PROPERTY;
	private static final String DRIVER_PATH_KEY_FIREFOX = GeckoDriverService.GECKO_DRIVER_EXE_PROPERTY;
	private static final String DRIVER_PATH_KEY_IE = InternetExplorerDriverService.IE_DRIVER_EXE_PROPERTY;

	
	private static WebDriverFactory instance;
	
	private SeleniumConfig seleniumConfig;
	
	private String browser;
	
	public static WebDriverFactory getInstance() {
		if (instance == null) {
			instance = new WebDriverFactory();
		}
		return instance;
	}
	
	protected WebDriverFactory() {
		seleniumConfig = SeleniumConfig.load();

		DesiredCapabilities capabilities = new DesiredCapabilities();
		capabilities.setCapability(CapabilityType.ACCEPT_SSL_CERTS, true);
		capabilities.setJavascriptEnabled(true);

		for (WebDriverConfig webDriverConfig : seleniumConfig.getWebDrivers()) {
			if (webDriverConfig.isUsed()) {
				browser = webDriverConfig.getBrowser();
				switch (webDriverConfig.getBrowser()) {
				case SeleniumConfig.BROWSER_FIREFOX:
					configFirefoxDriver(webDriverConfig);
					break;
				case SeleniumConfig.BROWSER_CHROME:
					configChromeDriver(webDriverConfig);
					break;
				case SeleniumConfig.BROWSER_IE:
					configInternetExplorerDriver(webDriverConfig);
					break;
				case SeleniumConfig.BROWSER_SAFARI:
					configSafariDriver(webDriverConfig);
					break;
				default:
				}
			}
		}
	}
	
	protected void configFirefoxDriver(WebDriverConfig webDriverConfig) {
		if (webDriverConfig.getVersion() >= WebDriverUtil.VERSION_FIREFOX_SELENIUM_3) {
			if (webDriverConfig.getDriver() != null) {
				System.setProperty(DRIVER_PATH_KEY_FIREFOX, webDriverConfig.getDriver());
			}
		}
	}

	protected void configChromeDriver(WebDriverConfig webDriverConfig) {
		if (webDriverConfig.getDriver() != null) {
			System.setProperty(DRIVER_PATH_KEY_CHROME, webDriverConfig.getDriver());
		}
	}
	
	protected void configInternetExplorerDriver(WebDriverConfig webDriverConfig) {
		if (webDriverConfig.getDriver() != null) {
			System.setProperty(DRIVER_PATH_KEY_IE, webDriverConfig.getDriver());
		}
	}
	
	protected void configSafariDriver(WebDriverConfig webDriverConfig) {
		// Path of Safari driver is always /usr/bin/safaridriver.
	}
	
	public RemoteWebDriver createWebDriver() {
		RemoteWebDriver webDriver = null;
		switch (browser) {
		case SeleniumConfig.BROWSER_FIREFOX:
			webDriver = new FirefoxDriver();
			break;
		case SeleniumConfig.BROWSER_CHROME:
			webDriver = new ChromeDriver();
			break;
		case SeleniumConfig.BROWSER_IE:
			webDriver = new InternetExplorerDriver();
			break;
		case SeleniumConfig.BROWSER_SAFARI:
			webDriver = new SafariDriver();
			break;
		default:
		}
		return webDriver;
	}

}
